A storage server is a processing system adapted to store and retrieve data on behalf of one or more client processing systems (“clients”) in response to input/output (I/O) client requests. A storage server can be used for many different purposes, such as to provide multiple users with access to shared data or to backup data.
One example of a storage server is a file server. A file server operates on behalf of one or more clients to store and manage shared files in a set of mass storage devices, such as magnetic or optical storage disks or tapes. The mass storage devices may be organized into one or more volumes of Redundant Array of Independent (or Inexpensive) Disks (RAID). Another example of a storage server is a device, which provides clients with block-level access to stored data, rather than file-level access, or a device, which provides clients with both file-level access and block-level access.
In a storage server, data gets corrupted or lost from time to time, for example, upon the failure of one of the mass storage devices. Therefore, it is common to implement techniques for protecting the stored data. Currently, these techniques involve calculating a data protection value (e.g., parity) and storing the parity in various locations. Parity may be computed as an exclusive-OR (XOR) of data blocks in a stripe spread across multiple disks in a disk array. In a single parity scheme, e.g. RAID-4 or RAID-5, an error can be corrected in any block in the stripe using a single parity block (also called “row parity”), which can be computed as a result of a logical operation on data blocks in a stripe. In a dual parity scheme, e.g. RAID Double Parity (RAID-DP), a technique invented by Network Appliance Inc. of Sunnyvale, Calif., errors resulting from a two-disk failure can be corrected using two parity blocks.
When one or more data blocks in a stripe are modified, a parity block has to be updated for that stripe. Two techniques are known for modifying data blocks and thus updating a parity block. According to a first method, known as “Read Modify Write” or “Parity By Subtraction Write” (also referred to herein as “a subtraction method”), data blocks that are being modified within a stripe and a parity block for the stripe are read into memory. Then an exclusive OR (XOR) operation is performed on the read data blocks and the parity block. The result of the XOR operation is XOR'ed with new data blocks to be written to compute new parity. Then, the result is written to the parity block in the stripe. When a large number of data blocks are modified, another method for writing data, known as “Write by Recalculation” (or as referred to herein, a “recalculation method”) is used. According to this method, data blocks within a stripe that are not to be modified are read into memory. To compute new parity, the read data blocks are XOR'ed with a result of the XOR operation on new data blocks. The result is written to a parity block in the stripe on a disk.
Prior to using disk arrays for the first time or prior to adding a disk to an existing array, disk drives are zeroed (a zero value is written to the disks) to ensure that parity for each stripe is consistent with the data blocks in the stripes. A disk can be added to the existing array, for example, when it replaces another disk or when the number of disks is expanded in the array. The process of zeroing the disk though can be time-consuming and might require up to eight hours to complete. Moreover, this time increases as disk drive capacities are increasing.
An alternative to zeroing disk drives would be to read all data blocks in each stripe, calculate the parity and write the parity onto the disk. Any write requests received to the stripes that already had the parity calculated and written could be performed using either the recalculation method or the subtraction method. Any write requests to the stripes that had not had the parity calculated and written would be done using the recalculation method. An advantage of this technique is that the disks could be used immediately after the array was created. One of the shortcomings of this technique though is that reading all data drives, computing parity, and writing the computed parity to the disk would take much longer than it would take to zero the drives. In addition, even though the array can be used while this reparity process is running, the overhead of the reparity process will affect the performance of the system. Moreover, any writes that have to be done using a recalculation method may not be as efficient as they would have been had they been done by the subtraction method (which again requires parity being consistent with all the data blocks in a stripe).
Accordingly, what is needed is a mechanism that eliminates the need to zero disk drives prior to adding them to the system without adding overhead of parity recomputation to the entire array.